package com.heima.wemedia.service.impl;

import com.heima.apis.article.IArticleClient;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.common.exception.CustomException;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.dtos.CommentManageDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.comment.dtos.CommentStatusDto;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.thread.WmThreadLocalUtil;
import com.heima.wemedia.pojos.ApComment;
import com.heima.wemedia.pojos.ApCommentLike;
import com.heima.wemedia.pojos.ApCommentRepayLike;
import com.heima.wemedia.service.CommentManageService;
import com.heima.wemedia.service.WmUserService;
import com.heima.wemedia.vos.CommentListVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: CommentManageServiceImpl
 * Description:
 * date: 2023/8/30 0030 17:20
 *
 * @author zHan
 */
@Service
@Slf4j
@Transactional
public class CommentManageServiceImpl implements CommentManageService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IArticleClient articleClient;

    /**
     * 查询评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findNewsComments(CommentManageDto dto) {
        // 判断用户是否登录
        WmUser wmUser = WmThreadLocalUtil.getUser();
        if (wmUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        dto.setAuthorId(wmUser.getId());
        return articleClient.findNewsComments(dto);
    }

    /**
     * 查看文章详情
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(CommentManageDto dto) {
        // 检查参数
        if (dto == null || dto.getArticleId() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        dto.checkParam();
        // 判断用户是否登录
        WmUser wmUser = WmThreadLocalUtil.getUser();
        if (wmUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 创建结果list集合
        List<CommentListVo> list = new ArrayList<>();
        // 查询集合对象
        // apComments
        List<ApComment> apComments =
                mongoTemplate.find(Query.query(Criteria.where("entryId").is(dto.getArticleId()))
                        .with(Sort.by(Sort.Direction.DESC, "createdTime")), ApComment.class);
        // apCommentRepays
        for (ApComment apComment : apComments) {
            // 创建vo对象
            CommentListVo commentListVo = new CommentListVo();
            // 赋值
            commentListVo.setApComments(apComment);
            // 查询 apCommentRepays
            List<com.heima.wemedia.pojos.ApCommentRepay> apCommentRepays =
                    mongoTemplate.find(Query.query(Criteria.where("commentId").is(apComment.getId()))
                                    .with(Sort.by(Sort.Direction.DESC, "updatedTime")),
                            com.heima.wemedia.pojos.ApCommentRepay.class);
            if (apCommentRepays != null && apCommentRepays.size() > 0) {
                commentListVo.setApCommentRepays(apCommentRepays);
            }
            list.add(commentListVo);
        }
        ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(),
                list.size());
        responseResult.setData(list);
        return responseResult;
    }

    @Autowired
    private WmUserService wmUserService;

    /**
     * 打开或关闭评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult updateCommentStatus(CommentStatusDto dto) {
        // 参数校验
        if (dto == null || dto.getArticleId() == null || dto.getOperation() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 判断用户是否登录
        WmUser wmUser = WmThreadLocalUtil.getUser();
        if (wmUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 得到作者id
        Integer authorId = wmUserService.getById(wmUser.getId()).getApAuthorId();
        // 如果是关闭评论，清空该文章所有评论，以及评论回复
        if (dto.getOperation() == 0) {
            Query articleQuery = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                    .and("authorId").is(authorId));
            // 查找该文章
            List<ApComment> apComments = mongoTemplate.find(articleQuery, ApComment.class);
            for (ApComment apComment : apComments) {
                // 得到所有该文章的点赞
                Query commentQuery = Query.query(Criteria.where("commentId").is(apComment.getId())
                        .and("authorId").is(authorId));
                List<com.heima.wemedia.pojos.ApCommentRepay> commentRepayList =
                        mongoTemplate.find(commentQuery,
                        com.heima.wemedia.pojos.ApCommentRepay.class);
                // 获取所有文章点赞的文章id
                List<String> commentRepayIdList = commentRepayList.stream()
                        .map(com.heima.wemedia.pojos.ApCommentRepay::getId)
                        .distinct()
                        .collect(Collectors.toList());
                //删除所有的评论回复点赞数据
                mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").in(commentRepayIdList)
                        .and("authorId").is(authorId)), ApCommentRepayLike.class);
                //删除该评论的所有的回复内容
                mongoTemplate.remove(commentQuery, com.heima.wemedia.pojos.ApCommentRepay.class);
                //删除评论的点赞
                mongoTemplate.remove(commentQuery, ApCommentLike.class);
            }
            // 删除评论
            mongoTemplate.remove(articleQuery, ApComment.class);
        }
        // 修改article_config表
        return articleClient.updateArticleConfig(dto);
    }

    /**
     * 回复评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult commentRepay(CommentRepaySaveDto dto) {
        // 参数校验
        if (dto == null || dto.getCommentId() == null || StringUtils.isBlank(dto.getContent())) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 评论内容大于140，报错
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(201, "评论内容不能大于140字");
        }
        // 判断用户是否登录
        WmUser wmUser = WmThreadLocalUtil.getUser();
        if (wmUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 得到作者id
        Integer authorId = wmUserService.getById(wmUser.getId()).getApAuthorId();
        // 根据用户id查询用户信息
        // 封装对象
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(authorId);
        apCommentRepay.setAuthorName(wmUserService.getById(wmUser.getId()).getName());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setLikes(0);
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setUpdatedTime(new Date());
        // 执行新增方法
        mongoTemplate.save(apCommentRepay);
        // 更新评论数
        // 查询 ApComment
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        // 数据不存在
        if (apComment == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 评论点赞
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        // 参数检验
        if (dto == null || dto.getCommentId() == null || dto.getOperation() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 判断用户是否登录
        WmUser wmUser = WmThreadLocalUtil.getUser();
        if (wmUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 得到作者id
        Integer authorId = wmUserService.getById(wmUser.getId()).getApAuthorId();
        // 查询 ApComment
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        // 数据不存在
        if (apComment == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 点赞
        if (dto.getOperation() == 0) {
            // ap_comment_like中新增数据
            com.heima.comment.pojos.ApCommentLike apCommentLike =
                    new com.heima.comment.pojos.ApCommentLike();
            apCommentLike.setAuthorId(authorId);
            apCommentLike.setCommentId(dto.getCommentId());
            mongoTemplate.save(apCommentLike);
            // ap_comment中的like加1
            apComment.setLikes(apComment.getLikes() + 1);
        } else if (dto.getOperation() == 1) {
            // 取消点赞
            // ap_comment_like中删除数据
            mongoTemplate.remove(Query.query(Criteria.where("commentId").is(dto.getCommentId())),
                    com.heima.comment.pojos.ApCommentLike.class);
            // ap_comment中的like减1
            apComment.setLikes(apComment.getLikes() - 1);
        }
        // 修改 ApComment
        mongoTemplate.save(apComment);
        return ResponseResult.okResult(apComment.getLikes());
    }

    /**
     * 删除评论
     *
     * @param commentId
     * @return
     */
    @Override
    public ResponseResult deleteComment(String commentId) {
        // 检查参数
        if (StringUtils.isBlank(commentId)) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        Query commentQuery = Query.query(Criteria.where("id").is(commentId));
        Query commentRepayQuery = Query.query(Criteria.where("commentId").is(commentId));
        //删除评论点赞
        mongoTemplate.remove(commentRepayQuery, ApCommentLike.class);
        // 删除评论
        mongoTemplate.remove(commentQuery, ApComment.class);
        // 查找所有文章评论
        List<ApCommentRepay> commentRepayList = mongoTemplate.find(commentRepayQuery,
                ApCommentRepay.class);
        // 获取点赞的文章id
        List<String> commentRepayIdList = commentRepayList.stream()
                .map(ApCommentRepay::getId)
                .distinct()
                .collect(Collectors.toList());
        //删除所有的评论回复点赞数据
        mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").in(commentRepayIdList))
                , ApCommentRepayLike.class);
        //删除该评论的所有的回复内容
        mongoTemplate.remove(commentRepayQuery, ApCommentRepay.class);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 删除评论回复
     *
     * @param commentRepayId
     * @return
     */
    @Override
    public ResponseResult deleteCommentRepay(String commentRepayId) {
        // 检查参数
        if (StringUtils.isBlank(commentRepayId)) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 获取点赞的文章id
        Query query = Query.query(Criteria.where("id").is(commentRepayId));
        List<ApCommentRepay> apCommentRepayList = mongoTemplate.find(query, ApCommentRepay.class);
        // 获取点赞的文章id
        List<String> apCommentRepayIdList = apCommentRepayList.stream()
                .map(ApCommentRepay::getCommentId)
                .distinct()
                .collect(Collectors.toList());
        //删除所有的评论回复点赞数据
        mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").in(apCommentRepayIdList))
                , ApCommentRepayLike.class);
        // 删除评论
        mongoTemplate.remove(query, com.heima.wemedia.pojos.ApCommentRepay.class);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
